package com.miyu.client1.service.bookAdmin.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.miyu.client1.dao.bookAdmin.bookAdminDao;
import com.miyu.client1.pojo.book.BookRuleSet;
import com.miyu.client1.service.bookAdmin.bookAdminService;
import com.miyu.client1.service.bookAdmin.checkRule.checkRule;
import com.miyu.client1.service.magic.impl.initDataCommon;
import com.miyu.client1.utils.bookUtils.*;
import com.miyu.client1.utils.ehcache.EhcacheUtil;
import com.miyu.client1.utils.redis.redisUtils.util.RedisListUtil;
import com.miyu.client1.utils.redis.redisUtils.util.RedisValUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Request;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Service
public class bookAdminServiceImpl implements bookAdminService {
    @Resource
    private bookAdminDao dao;

    @Override
    public JSONArray queryBookList(JSONObject param) {
        System.out.println(param);
            StringBuffer sql = new StringBuffer();
            sql.append(" select bli.book_id bookId ,br.sys_source_name sysSourceName, book_name bookName,book_author bookAuthor,book_kind bookKind, ");
            sql.append(" book_state bookState,book_duce bookDuce,book_source  bookSource,book_cover bookCover,book_last_chapter bookLastChapter,");
            sql.append(" book_last_chapter_url bookLastChapterUrl, book_source_name   bookSourceName");
            sql.append(" from book_list_info bli left join book_rule br on bli.book_rule_source = br.book_id");
            sql.append("  where 1=1 ");
            if (param.containsKey("bookInfo")){
                if(param.getString("bookInfo").length()>0)
                    sql.append(" and (book_name like '%").append(param.getString("bookInfo")).append("%' or book_author like '").append(param.getString("bookInfo")).append("%'  )");
            }
            sql.append(" limit 0,300");
        return dao.queryJSONArrayBySql(sql.toString());
    }

    @Override
    public JSONObject queryBookChapterList(JSONObject param) {
        JSONObject ds = new JSONObject();

        StringBuffer sql = new StringBuffer();
        sql.append(" select chapter_id chapterId, book_id bookId,chapter_source chapterSource,chapter_num chapterNum,chapter_name chapterName ,chapter_context chapterContext from book_chapter  ");
        sql.append("  where book_id='").append(param.getString("bookId")).append("'");
        sql.append(" ORDER BY chapter_num ");
        JSONArray chapter = dao.queryJSONArrayBySql(sql.toString());
        ds.put("zjList",chapter);
        ds.put("title",param);
        return ds;
    }

    /**
     * 章节查询
     * @param param
     * @return
     */
    @Override
    public JSONObject readBookChapter(JSONObject param) {
        Request request = new Request();
        ExecutorService exec = Executors.newFixedThreadPool(1);//工头
        request.putExtra("type","2");
        request.putExtra("bookRule",param);
        request.setUrl(param.getString("chapterSource"));
        request.putExtra("chapterInfo",param);
      //  exec.submit(new initDataTask(request,"1"));
        initDataCommon.initData(request);
        JSONObject chapterInfo = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache",param.getString("chapterId"));
        EhcacheUtil.getInstance().remove("bookEhcache", param.getString("chapterId"));
        return chapterInfo;
    }

    /**
     *章节查询
     * @param param
     * @return
     */
    @Override
    public JSONObject queryChapter(JSONObject param) {
        String lastUrl = param.getString("bookLastChapterUrl");
        String chapterId = BookCommutils.MD5(lastUrl);
        StringBuffer sql = new StringBuffer();
        sql.append(" select chapter_id chapterId,book_id bookId,chapter_source chapterSource,chapter_num chapterNum,chapter_name chapterName,chapter_context chapterContext ");
        sql.append(" from book_chapter ts ");
        sql.append(" where chapter_id ='").append(chapterId).append("'");
        return dao.queryJSONObjectBySql(sql.toString());
    }

    /**
     * 规则校验取值数据
     * 校验规则取值数据
     * 单值校验 url 以及规则xpatch 返回数据
     * @param param
     * @return
     */
    @Override
    public JSONObject CheckRule(JSONObject param) {

        Request req = new Request();
        req.setUrl(param.getString("url"));
        req.putExtra("rule",param.getString("rule"));
        checkRule.checkRule(req);
        JSONObject checkRule = (JSONObject) EhcacheUtil.getInstance().get("bookEhcache","checkRule");
        System.out.println(checkRule);


        return checkRule;
    }

    /**
     * 规则处理
     * @param param
     * @return
     */
    @Override
    public JSONObject saveOrUpdateBookRuleSet(JSONObject param) {

        //只有在新建时才创建动态表
        System.out.println("ruleId>>>>>>>>>"+param);
        System.out.println("ruleSet>>>>>>>>>"+param.getJSONObject("ruleSet"));
     //   System.out.println("ruleId>>>>>>>>>"+ruleId);

        BookRuleSet brs = new BookRuleSet();

        StringBuffer sql = new StringBuffer();

     String ruleId ="";
        if(StringUtils.isNotBlank(param.getString("ruleId"))){
            ruleId=param.getString("ruleId");
            sql.append(" update book_rule_set set ");
            sql.append(" rule_name='").append(param.getString("ruleName")).append("',");
            sql.append(" root_source='").append(param.getString("rootSource")).append("',");
            sql.append(" root_search='").append(param.getString("rootSearch")).append("',");
            sql.append(" rule_set='").append(param.getJSONObject("ruleSet").toString()).append("'");
            sql.append(" where rule_id='").append(ruleId).append("'");
        }
        else{
           ruleId = BookCommutils.getUUID();
//            brs.setRuleId(ruleId);
            sql.append(" insert into book_rule_set ( rule_id,rule_name,root_source,root_search,root_type,rule_book_list,rule_chapter_list,is_stop,rule_set)");
            sql.append(" values (");
            sql.append("'").append(ruleId).append("',");
            sql.append("'").append(param.getString("ruleName")).append("',");
            sql.append("'").append(param.getString("rootSource")).append("',");
            sql.append("'").append(param.getString("rootSearch")).append("',");
            sql.append("'").append("GET").append("',");
            sql.append("'").append("book_"+ruleId).append("',");
            sql.append("'").append("chapter_"+ruleId).append("',");
            sql.append("'0',");
            sql.append("'").append(param.getJSONObject("ruleSet").toString()).append("')");
        }
        try {
            System.out.println(sql);
            dao.doExecute(sql.toString());
            param.put("ruleBookList","book_"+ruleId);
            param.put("ruleChapterList","chapter_"+ruleId);
            createtable(param);
        }catch (Exception e){

        }

        return param;
    }

    /**
     * 解析规则查询
     * @param param
     * @return
     */
    @Override
    public JSONArray queryRuleSet(JSONObject param) {
        String ruleName = param.getString("ruleName");
        StringBuffer sql = new StringBuffer();
        sql.append("select  ");
        sql.append(" rule_id ruleId, rule_name ruleName, root_source rootSource,root_search rootSearch,root_type rootType,rule_book_list ruleBookList,rule_chapter_list ruleChapterList,");
        sql.append(" is_stop isStop,rule_set ruleSet");

        sql.append("    from book_rule_set ");
        if(StringUtils.isNotBlank(ruleName))
            sql.append("where rule_name like '%").append(ruleName).append("%'");

        return dao.queryJSONArrayBySql(sql.toString());
    }

    /**
     * 规则删除
     * @param param
     * @return
     */
    @Override
    public JSONObject deleteRuleSet(JSONArray param) {
        System.out.println(param);
        for (int i = 0; i < param.size(); i++) {
            JSONObject jo = param.getJSONObject(i);
            deleteBookRule(jo);
        }
        JSONObject rs = new JSONObject();
        rs.put("msg","删除成功");
        rs.put("code","1");
        return rs;
    }
    public void deleteBookRule(JSONObject jo){

        String ruleId = jo.getString("ruleId");
        String bookList = jo.getString("ruleBookList");
        String chapterList = jo.getString("ruleChapterList");
        dao.deleteById(ruleId);
        StringBuffer sql = new StringBuffer();
        sql.append("drop table ").append(bookList);
        dao.doExecute(sql.toString());
        //所有分表
        String[] chTable = BookCommutils.chTable();
        for (int i = 0; i <chTable.length ; i++) {
            sql.setLength(0);
            sql.append("drop table ").append(chapterList).append("_").append(chTable[i]).append(chapterList);
            dao.doExecute(sql.toString());
        }

    }

    public void  createtable(JSONObject param) {
        String ruleBookList = param.getString("ruleBookList").trim();
        String ruleChapterList = param.getString("ruleChapterList").trim();
        StringBuffer sql = new StringBuffer();
        boolean isMysql = BookCommutils.IsMysql();
        if (isMysql) {
            //判断吧表是否存在
            if (checkExists(ruleBookList)) {
                sql.append(" create table ").append(ruleBookList).append(" (");
                sql.append(" book_id varchar (32) COMMENT '书籍列表主键' ,");
                sql.append(" rule_id varchar (32) COMMENT '规则来源' ,");
                sql.append(" book_source varchar(100) DEFAULT NULL COMMENT '书籍来源',");
                sql.append(" book_name varchar(100) DEFAULT NULL COMMENT '数据名称',");
                sql.append(" book_chapter_source varchar(100) DEFAULT NULL COMMENT '章节表',");
                sql.append(" book_author varchar(50) DEFAULT NULL COMMENT '作者',");
                sql.append(" book_kind varchar(50) DEFAULT NULL COMMENT '类别', ");
                sql.append(" book_state varchar(20) DEFAULT NULL COMMENT '状态', ");
                sql.append(" book_cover varchar(100) DEFAULT NULL COMMENT '图片',");
                sql.append(" book_duce varchar(500) DEFAULT NULL COMMENT '简介',");
                sql.append(" book_last_chapter varchar(100) DEFAULT NULL COMMENT '最新章节名称',");
                sql.append(" book_last_chapter_url varchar(100) DEFAULT NULL COMMENT '最新章节链接',");
                sql.append(" book_last_chapter_date varchar(20) DEFAULT NULL   COMMENT '最后更新日期',");
                sql.append(" book_date   timestamp not null default current_timestamp COMMENT '操作时间',");
                sql.append(" PRIMARY KEY (book_id) ");
                sql.append("    ,INDEX book_ (book_name, book_author)   ");
                sql.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8 ");
                dao.doExecute(sql.toString());

            }
            if (checkExists(ruleChapterList)) {
                String[] chTable = BookCommutils.chTable();
                for (int i = 0; i < chTable.length; i++) {
                    sql.setLength(0);
                    sql.append(" create table ").append(ruleChapterList).append("_").append(chTable[i]).append(" ( ");
                    sql.append("  chapter_id varchar(32) NOT NULL COMMENT '章节主键',");
                    sql.append(" book_id varchar(32) DEFAULT NULL COMMENT '书籍明细主键',");
                    sql.append(" chapter_source varchar(255) DEFAULT NULL COMMENT '章节来源',");
                    sql.append("  chapter_num int(8) DEFAULT NULL COMMENT '序列号', ");
                    sql.append(" chapter_name varchar(100) DEFAULT NULL COMMENT '章节名称',");
                    sql.append(" chapter_context mediumtext COMMENT '章节内容',");
                    sql.append(" PRIMARY KEY (chapter_id) ");
                    sql.append("    ,INDEX chapter_ (book_id, chapter_num asc )   ");
                    sql.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8 ");
                    dao.doExecute(sql.toString());
                }
            }

        } else {
            //判断吧表是否存在
            if (checkExists(ruleBookList)) {
                sql.append(" create table ").append(ruleBookList).append(" (");
                sql.append(" book_id varchar (32) primary key not null ,");
                sql.append(" rule_id varchar (32)  ,");
                sql.append(" book_source varchar(100) ,");
                sql.append(" book_name varchar(100) ,");
                sql.append(" book_chapter_source varchar(100) ,");
                sql.append(" book_author varchar(50) ,");
                sql.append(" book_kind varchar(50) , ");
                sql.append(" book_state varchar(20) , ");
                sql.append(" book_cover varchar(100) ,");
                sql.append(" book_duce varchar(1500) ,");
                sql.append(" book_last_chapter varchar(100) ,");
                sql.append(" book_last_chapter_url varchar(100) ,");
                sql.append(" book_last_chapter_date varchar(20) ,");
                sql.append(" book_date  DATE not null default getdate()  ");
                sql.append(")  ");
                dao.doExecute(sql.toString());
            }
            if (checkExists(ruleChapterList)) {
                String[] chTable = BookCommutils.chTable();
                for (int i = 0; i < chTable.length; i++) {
                    sql.setLength(0);
                    sql.append(" create table ").append(ruleChapterList).append("_").append(chTable[i]).append(" ( ");
                    sql.append("  chapter_id varchar(32) primary key not null,");
                    sql.append(" book_id varchar(32) ,");
                    sql.append(" chapter_source varchar(255) ,");
                    sql.append("  chapter_num int , ");
                    sql.append(" chapter_name varchar(150) ,");
                    sql.append(" chapter_context nvarchar(max)");
                    sql.append(") ");
                    dao.doExecute(sql.toString());
                    sql.setLength(0);
                    sql.append("create index idex_chapter on ").append(ruleChapterList).append("_").append(chTable[i]).append("(book_id,chapter_num asc)");
                    System.out.println(sql);
                    dao.doExecute(sql.toString());
                }
            }
        }
    }

    /**
     * 检测表是否存在
     * @param ruleBookList
     * @return
     */
    private boolean checkExists(String ruleBookList) {
        StringBuffer sql = new StringBuffer();
        sql.append(" select count(0) count  from information_schema.TABLES t where  t.TABLE_NAME ='").append(ruleBookList).append("'");
        JSONObject rs = dao.queryJSONObjectBySql(sql.toString());
        if(rs.getString("count").equals("0"))
            return true;
        return false;
    }

    @Autowired
    private RedisValUtil rv;
    @Autowired
    private RedisListUtil rdList;
    /**
     * 初始化小说章节
     * @param param
     * @return
     */
    @Override
    public JSONObject initData(JSONObject param){
        JSONObject bs= new JSONObject();
        JSONObject br = dao.queryJSONObjectBySql(BookCommutils.bookRuleStr(param));
       // rv.set(1,"initDataChapter",br);
        param.put("type","initData");
        JSONObject reset = JSONObject.parseObject(br.getString("ruleSet"));
        int start = param.getInteger("start");
        int end = param.getInteger("end");
        ExecutorService svr = Executors.newCachedThreadPool();
        ExecutorService exec = Executors.newFixedThreadPool(1);//工头
        svr.submit(new saveRedisThead("initData"));
        for(int i=start;i<=end;i++){
            JSONObject req = new JSONObject();
           String  url = param.getString("url").replace("*",String.valueOf(i));
            List<String> set = new ArrayList<>();
            String bookId = BookCommutils.MD5(url);
            set.add("bookChapterList");
            JSONObject cond = new JSONObject();
            cond.put("key",bookId);
            cond.put("num",set);
            req.put("ruleSet",reset);
            req.put("cond",cond);
            req.put("thread",1);
            req.put("param",param);//附加参数
            req.put("url",url);
            exec.submit(new JXPageRuleThread(req,"1"));
        }

       // System.out.println(">>>>>>>"+rdList.getListAll(1,"initDataChapter",JSONObject.class));
     return null;



    }


    /**
     * 初始化章节 更新章节内容
     * @param param
     * @return
     */
    @Override
    public JSONObject initDataChapter(JSONObject param) {
        JSONObject br = dao.queryJSONObjectBySql(BookCommutils.bookRuleStr(param));
        StringBuffer sql = new StringBuffer();
        sql.append("select book_id bookId,book_chapter_source bookChapterSource from ").append(br.getString("ruleBookList"));
        sql.append(" where book_id = '").append("00009bc18eac16bc1e760d3446bd77f9").append("'");

        JSONArray ds = dao.queryJSONArrayBySql(sql.toString());
        JSONObject reset = JSONObject.parseObject(br.getString("ruleSet"));
        ExecutorService exec = Executors.newFixedThreadPool(4);//工头
        //书籍取出明细章节
        for (int i = 0; i < ds.size(); i++) {
            JSONObject ch = ds.getJSONObject(i);
            sql.setLength(0);
            sql.append("select  chapter_id chapterId,chapter_source chapterSource from ").append(ch.getString("bookChapterSource"));
            sql.append(" where book_id = '").append(ch.getString("bookId")).append("'");
            sql.append("");
            JSONArray chList = dao.queryJSONArrayBySql(sql.toString());
            for (int j = 0; j < chList.size(); j++) {
                param.clear();
                JSONObject chapter = chList.getJSONObject(j);
                JSONObject req = new JSONObject();
                JSONObject cond = new JSONObject();
                List<String> set = new ArrayList<>();

                param.put("type","initDataChapter");
                param.put("bookId",ch.getString("bookId"));
                param.put("chapterId",chapter.getString("chapterId"));
                param.put("tableId",ch.getString("bookChapterSource"));
                //String bookId = ch.getString("bookId");
                set.add("chapterContext");

                cond.put("key",chapter.getString("chapterId"));
                cond.put("num",set);
                req.put("ruleSet",reset);
                req.put("cond",cond);
                req.put("thread",1);
                req.put("param",param);//附加参数
                req.put("url",chapter.getString("chapterSource"));
                //RuleJXData.RuleJXDataPage(req);
                exec.submit(new JXPageRuleThread(req,"1"));
            }

        }
        return null;
    }


}
